#include "database.h"
#include <QVariant>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>

Database::Database(ChatterBoxServer *server) : chatSrv(server)
{
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("top");
    db.open();
    SQLreloadUsers();
}

Database::~Database()
{
    db.close();
}

bool Database::SQLuserExist(QString name)
{
    QSqlQuery query(db);
    query.exec("select 1 from users where `name` = '" + name.toLower() + "'");
    if (!query.first())
        return false;
    return true;
}

void Database::SQLaddUser(QString name, int score)
{
    QSqlQuery query(db);
    query.exec("insert into users values('" +  name.toLower() + "', " + QString::number(score) + ")");
    addUser(name, score);
}

void Database::SQLsetScore(QString name, int score)
{
    QSqlQuery query(db);
    query.exec("update users set score=" +  QString::number(score) + " where name = '" + name.toLower()  + "'");
    setScore(name, score);
}

int Database::SQLgetScore(QString name)
{
    QSqlQuery query(db);
    query.exec("select score from users where `name` = '" + name.toLower() + "'");
    query.next();
    return query.value(0).toInt();
}

void Database::SQLaddScore(QString name, int score)
{
    QSqlQuery query(db);
    int realScore = SQLgetScore(name) + score;
    query.exec("update users set score=" +  QString::number(realScore) + " where name = '" + name.toLower()  + "'");
    addScore(name,score);
}

void Database::SQLreloadUsers()
{
    QSqlQuery query(db);
    user player;
    usersList.clear();
    query.exec("select name, score from users");
    while (query.next())
    {
        player.name = query.value(0).toString();
        player.score = query.value(1).toInt();
        usersList.append(player);
    }
}

void Database::addUser(QString name, int score)
{
    user temp;
    temp.name = name;
    temp.score = score;
    usersList.append(temp);
}

void Database::setScore(QString name, int score)
{
    for (int i = 0; i < usersList.size(); ++i)
        if (usersList.at(i).name.toLower() == name.toLower())
        {
            user good = usersList.at(i);
            good.score = score;
            usersList.replace(i,good);
            return;
        }

    qDebug() << "setScore with nonexisting user. this should not happen.";
    addUser(name,score);
}

int Database::getScore(QString name)
{
    for (int i = 0; i < usersList.size(); ++i)
        if (usersList.at(i).name.toLower() == name.toLower())
            return usersList.at(i).score;

    qDebug() << "getScore with nonexisting user. this should not happen.";
    return 0;
}

void Database::addScore(QString name, int score)
{
    for (int i = 0; i < usersList.size(); ++i)
        if (usersList.at(i).name.toLower() == name.toLower())
        {
            user good = usersList.at(i);
            good.score += score;
            usersList.replace(i,good);
            return;
        }

    addUser(name,score);
}

bool user::operator<(const user other) const
{
    return this->score > other.score;
}


int Database::getRank(QString name)
{
    qSort(usersList.begin(), usersList.end());
    for (int i = 0; i < usersList.size(); ++i)
        if (usersList.at(i).name.toLower() == name.toLower())
            return i+1;

    return 0;
}

bool Database::userExists(QString name)
{
    for (int i = 0; i < usersList.size(); ++i)
        if (usersList.at(i).name.toLower() == name.toLower())
            return true;

    return false;
}

void Database::showTop3()
{
    qSort(usersList.begin(), usersList.end());
    chatSrv->sendText("Top3 players: ");
    for (int i = 0; i < usersList.size() && i < 3; ++i)
        chatSrv->sendText(QString::number(i+1) + ". " + usersList.at(i).name + " Score(" + QString::number(usersList.at(i).score) + ")");
}

void Database::showScore(QString name)
{
    if (!userExists(name))
    {
        chatSrv->sendText("User not on list.");
        return;
    }
    QString info;
    info = name + " Score(" + QString::number(getScore(name)) + ") Rank(" + QString::number(getRank(name)) + ")";
    chatSrv->sendText(info);
}
